package com.ruoyi.web.controller.system;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.domain.model.PasswordLoginBody;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.wechat.WeChatConstants;
import com.ruoyi.common.utils.wechat.WeChatLoginVo;
import com.ruoyi.common.utils.wechat.WeChatUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Set;

/**
 * 登录验证
 *
 * @author ruoyi
 */
@RestController
@Api(tags = "登陆接口")
public class SysLoginController {

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysLoginService loginService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 后台登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody) {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid(), loginBody.getUserType());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /**
     * app账号密码登陆
     */
    @PostMapping("/app/loginbypassword")
    @ApiOperation("app账号密码登陆")
    public AjaxResult loginbypassword(@RequestBody PasswordLoginBody.Login loginBody) {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /**
     * app手机号验证码登陆
     */
    @GetMapping("/app/loginByPhone")
    @ApiOperation("app手机号验证码登陆")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String")
    })
    public AjaxResult loginByPhone(String phone, String code, String openId) {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.loginByPhone(phone, code);
        userMapper.updateUserByPhone(phone, openId);
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /**
     * app微信登陆
     */
    @GetMapping("/app/loginByOpenId")
    @ApiOperation("app微信登陆")
    public AjaxResult loginByOpenId(String openId) {
        if (StringUtils.isNull(openId)) {
            return AjaxResult.error("缺失参数openId");
        }
        SysUser user = userMapper.selectByOpenId(openId);
        if (StringUtils.isNull(user)) {
            return AjaxResult.error(201, "还没有绑定手机号，请先绑定");
        }
        AjaxResult ajax = new AjaxResult();
        String token = loginService.loginByWx(openId, user.getPhonenumber());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /**
     * 微信授权登录
     */
    @PostMapping("/weLogin")
    @ApiOperation("小程序微信授权登录")
    public AjaxResult weChatOauth(@RequestBody WeChatLoginVo weChatLogin) {
        String code = weChatLogin.getCode();
        if (StringUtils.isEmpty(code)) {
            return AjaxResult.error("code获取失败");
        }
        if (WeChatConstants.REFUSE_CODE.equals(code)) {
            return AjaxResult.error("用户取消授权");
        }
        JSONObject oauthInfo;
        try {
            String response = restTemplate.getForObject(WeChatConstants.getOauthUrl(code), String.class);
            oauthInfo = JSONObject.parseObject(response);
        } catch (Exception e) {
            throw new CustomException(e.getMessage());
        }
        String sessionKey = oauthInfo.getString("session_key");
        String openId = oauthInfo.getString("openid");
        //根据sessionKey解密数据
        String phoneInfo = WeChatUtils.getUserInfo(weChatLogin, sessionKey);
        if (StringUtils.isNull(phoneInfo)) {
            return AjaxResult.error("获取用户手机号信息失败，请重新尝试");
        }
        JSONObject results = JSONObject.parseObject(phoneInfo);
        String phoneNumber = results.getString("phoneNumber");
        SysUser user = userMapper.selectUserByPhoneNumber(phoneNumber, UserConstants.APP_USER);
        if (StringUtils.isNull(user)) {
            AjaxResult ajax = AjaxResult.success();
            ajax.put("register", "0");
            return ajax;
        } else {
            AjaxResult ajax = AjaxResult.success();
            ajax.put("register", "1");
            String token = loginService.loginByWx(openId, phoneNumber);
            ajax.put(Constants.TOKEN, token);
            return ajax;
        }
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo() {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser user = userMapper.selectUserById(loginUser.getUser().getUserId());
        // 查询还需要多少人可以升级为团长
        Integer peopleNumber = UserConstants.TEAM_THRESHOLD - userMapper.getMyInvitees(user.getUserId());
        user.setPeopleNumber(peopleNumber);
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters() {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        // 用户信息
        SysUser user = loginUser.getUser();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(user.getUserId());
        return AjaxResult.success(menuService.buildMenus(menus));
    }
}
